import React, { lazy, ComponentType } from 'react';
import {
    BrowserRouter,
    Routes,
    Route,
    generatePath,
    Navigate,
    useLocation,
    useParams,
} from 'react-router-dom';

export interface RouteConfig {
    path: string;
    component: string | (() => { default: ComponentType<any> }) | (() => JSX.Element);
    redirect?: string;
}


// 路由组件属性
interface RouteProps {
    routes: RouteConfig[];
    fallback?: React.ReactNode; // 加载中的回退UI
}

function NavigateWithParams(props: { to: string }) {
    const params = useParams();
    let to = generatePath(props.to, params);
    const location = useLocation();

    const queryAndHash = location.search + location.hash;
    to += queryAndHash;

    const propsWithParams = {
        ...props,
        to,
    };
    return <Navigate replace={true} {...propsWithParams} />;
}


// 解析路径别名（将 @/ 替换为实际路径）
const resolveAlias = (path: string) => {
    return path.replace(/^@\//, '/src/');
};

const isRoutePath = (route: string | any): boolean => {
    return route && typeof route === 'string';
};

// 动态加载组件
const defineRoutes = (route: string | any): React.ReactNode => {
    // 处理路径字符串
    if (isRoutePath(route)) {
        const resolvedPath = resolveAlias(route);
        const LazyComponent = lazy(() => import(resolvedPath));

        return (
            <React.Suspense fallback={<div></div>}>
                <LazyComponent />
            </React.Suspense>
        );
    }


    const LazyComponent = route;
    // 处理组件对象
    return (
        <React.Suspense fallback={<div></div>}>
            <LazyComponent />
        </React.Suspense>
    );
};


function createClientRoutes(route: any) {
    const { redirect } = route;
    return redirect ? (
        <NavigateWithParams to={redirect} />
    ) : (
        <Route
            key={route.path}
            path={route.path}
            element={defineRoutes(route?.component)}
        />
    );
}

const RouteComponent: React.FC<RouteProps> = (props) => {
    const { routes } = props;
    return (
        <BrowserRouter>
            <Routes>
                {routes.map((route) => {
                    return (
                        createClientRoutes(route)
                    );
                })}
            </Routes>
        </BrowserRouter>
    );
};

export default RouteComponent;